'use strict';

const Subscription = require('egg').Subscription;
const Fs = require('fs');
const Path = require('path');

/**
 * 删除缓存
 */
class DeleteCache extends Subscription {
  // 通过 schedule 属性来设置定时任务的执行间隔等配置
  static get schedule() {
    return {
      interval: 1000 * 60 * 60 * 24, // 每天清除一次
      type: 'all', // 指定所有的 worker 都需要执行
    };
  }

  // subscribe 是真正定时任务执行时被运行的函数
  async subscribe() {
    // 删除本地文件缓存
    const path = Path.resolve(__dirname, '../public/up-image/');
    this.getFiles(path);

    // 清除数据库日志缓存
    this.clearMongodb('LogServerError', 'date');
    this.clearMongodb('LogServerProcess', 'date');
    this.clearMongodb('LogWebAjax', 'date');
    this.clearMongodb('LogWebError', 'date');
    this.clearMongodb('LogWebProcess', 'date');

    // 清除JSON数据缓存
    this.clearMongodb('CacheData', 'date', 1000 * 3600 * 24 * 7);

    // 清除30天前的短连接
    this.clearMongodb('ShortConnection', 'date', 1000 * 60 * 60 * 24);
  }

  /**
   * 获取所有文件
   * @param {*} path 文件路径
   */
  getFiles(path) {
    const fileNames = Fs.readdirSync(path);
    fileNames.forEach(item => {
      const filePath = Path.join(path, item);
      const files = Fs.statSync(filePath);
      const isDir = files.isDirectory();
      const createTime = new Date(files.ctime).getTime();
      const nowTime = new Date().getTime();
      const timeCha = 1000 * 60 * 60 * 24 * 30;
      if (isDir) {
        this.getFiles(filePath);
        const fileNames = Fs.readdirSync(filePath);
        if (fileNames.length === 0) {
          Fs.rmdirSync(filePath);
        }
      } else {
        if (nowTime - createTime > timeCha) {
          Fs.unlinkSync(filePath);
        }
      }
    });
  }

  /**
   * 清除数据库中的数据
   * @param {*} modelName 数据库名称
   * @param {*} keyName 判断的时间字段
   * @param {*} dateNum 存储时间
   */
  async clearMongodb(modelName, keyName, dateNum = 1000 * 60 * 60 * 24 * 30) {
    const Model = this.ctx.model[modelName];
    const p = {};
    // 获取30天之前的时间
    const date = new Date(new Date().getTime() - dateNum);
    p[keyName] = {
      $lt: date,
    };
    await Model.deleteMany(p);
  }
}

module.exports = DeleteCache;
